package pers.sakurasora.calendar.util;

/**
 * @FileName InputFormatUtilImpl.java 
 * @author SakuraSora
 * @Email 1468071675@qq.com
 * @DateTime 2019年1月14日 下午4:58:37
 *
 * @Description
 *				<p>检验用户输入的数据格式是否合法</p>
 */
public class InputFormatUtil {
	/**
	 * 存放平年每月天数的整型数组(常量)
	 */
	private static final int[] DAYS_OF_MONTH = {31,28,31,30,31,30,31,31,30,31,30,31};
	/**
	 * 匹配由8位数字组成合法日期的字符串的正则表达式
	 */
	private static String sPatternDate = "(?!0000)^(?:(?:(?:(?=\\d{2}(?:(?:[02468][048])|(?:[13579][26])))\\d{4}02(?!00)[0-2]\\d))|(?:\\d{4}(?:(?:(?:(?:0[469])|(?:11))(?!00)(?:(?:[0-2]\\d)|(?:30)))|(?:(?:(?:0[13578])|(?:1[02]))(?!00)(?:(?:[0-2]\\d)|(?:3[01])))|(?:02(?!(?:00)|(?:29))[0-2]\\d))))$";
	
	/**
	 * 使用正则表达式匹配日期格式:<br>
	 *    判断传入的字符串是不是由8位表示日期的数字组成<br>
	 * @param date 日期字符串
	 * @return
	 * 			匹配--true<br>
	 * 			不匹配--false<br>
	 * @throws Exception 
	 */
	public static boolean datePattern(String sDate)
        throws Exception 
	{
		if (sDate.matches(sPatternDate)) {
			return true;
		}
		else {
			throw new Exception("输入日期不合法！");
		}
	}

	/**
	 * 检验日期格式（不使用正则表达式匹配）:<br>
	 *    判断传入的字符串是不是由8位表示合法日期的数字组成<br>
	 * @param date 日期字符串
	 * @return
	 * 			匹配--true<br>
	 * 			不匹配--false<br>
	 * @throws Exception 
	 */
	public static boolean dateCheck(String sDate)
        throws Exception 
	{
		boolean result = true;
		
		/**
		 * 先判断日期字符串长度是不是8位<br>
		 * 再判断日期字符串是不是由纯数字组成<br>
		 * 最后判断日期的合法性（如20190229不存在）:<br>
		 * 		1、如果是0000年，抛出“年份不存在”<br>
		 * 		2、如果月份超出范围，抛出“月份不存在”<br>
		 * 		3、如果日超出范围（闰年2月），抛出“日期不存在”<br>
		 * 		4、如果日超出范围（除闰年2月的其他情况），抛出“日期不存在”
		 */
		if (sDate.length() != 8) {
			result = false;
			throw new Exception("日期长度必须是8位！");
		}
		
		for (int i = 0; i < sDate.length(); i++) {
			if (sDate.charAt(i) < '0' || sDate.charAt(i) > '9') {
				result = false;
				throw new Exception("日期必须由8位纯数字组成!");
			}
		}
		
		int iYear = Integer.parseInt(sDate.substring(0, 4)); // 注意不是sDate.substring(0, 3)
		int iMonth = Integer.parseInt(sDate.substring(4, 6));
		int iDate = Integer.parseInt(sDate.substring(6, 8));
		
		if (iYear < 1) {
			result = false;
			throw new Exception("年份不存在！");
		}
		
		if (iMonth < 1 || iMonth > 12) {
			result = false;
			throw new Exception("月份不存在！");
		}
		
		if (DateUtil.isLeapYear(iYear) && iMonth == 2) {
			if (iDate < 0 || iDate > 29) {
				result = false;
				throw new Exception("日期不存在！");
			}
		}
		
		if ((DateUtil.isLeapYear(iYear) && iMonth != 2) || DateUtil.isLeapYear(iYear) == false) {
			if (iDate < 0 || iDate > DAYS_OF_MONTH[iMonth-1]) {
				result = false;
				throw new Exception("日期不存在！");
			}
		}
		return result;
	}
}
